import json
import logging
from typing import Union, Optional, Any
from services import service_mapper, cache, video_download
from model import ErrorResult, VideoType
from tools import store
from model import Msg

logger = logging.getLogger('request')


def get_info(url):
    vtype, url = get_vtype(url)
    if vtype is None:
        return Msg.failed(ErrorResult.URL_NOT_INCORRECT.get_data())

    token = store.get_token(vtype, url)
    info = cache.get(token)
    if info is not None:
        dic = info.to_dict()
        dic['token'] = token
        return Msg.success(dic)

    logger.info(f'get {vtype.value} video info ==> {url}.')

    service = service_mapper.get_service(vtype)
    result = service.get_info(url)

    if result.is_success():
        info = result.get_data()
        cache.save(token, info)
        dic = info.to_dict()
        dic['token'] = token
        return Msg.success(dic)
    return Msg.failed(result.get_data())


def download_file(url):
    if url is None :
        return
    vtype, url = get_vtype(url)
    token = store.get_token(vtype, url)
    info = cache.get(token)
    if info is None:
        return ErrorResult.VIDEO_INFO_NOT_FOUNT.get_data()

    logger.info(f'download {info.platform.value} ==> {info.desc}.')
    return video_download.download(info)


def get_vtype(url: str) -> (Optional[VideoType], str):
    for v, service in service_mapper.ServiceMapper.items():
        share_url = service.get_url(url)
        if share_url:
            return v, share_url
    return None, ''


def check_vtype(vtype: VideoType, url: str) -> Union[Optional[VideoType], Any]:
    if vtype is not VideoType.AUTO:
        return vtype

    for v, service in service_mapper.ServiceMapper.items():
        if service.get_url(url):
            return v
    return None
